package com.unidt.www.module.expert.job.service.impl;

import cn.hutool.core.date.DateUtil;
import com.unidt.www.framework.common.core.KeyValue;
import com.unidt.www.framework.common.util.string.RandomUtils;
import com.unidt.www.framework.sms.core.client.SmsClient;
import com.unidt.www.framework.sms.core.client.SmsClientFactory;
import com.unidt.www.framework.sms.core.client.SmsCommonResult;
import com.unidt.www.framework.sms.core.client.dto.SmsSendRespDTO;
import com.unidt.www.framework.sms.core.enums.SmsChannelEnum;
import com.unidt.www.module.expert.domain.ExpertInvitationDo;
import com.unidt.www.module.expert.domain.ExpertInvitationRuleDo;
import com.unidt.www.module.expert.domain.ExpertRuleUserDo;
import com.unidt.www.module.expert.job.service.IExpertSmsService;
import com.unidt.www.module.expert.mapper.ExpertInvitationMapper;
import com.unidt.www.module.expert.mapper.ExpertInvitationRuleMapper;
import com.unidt.www.module.expert.mapper.ExpertRuleUserMapper;
import com.unidt.www.module.system.dal.dataobject.sms.SmsTemplateDO;
import com.unidt.www.module.system.dal.mysql.sms.SmsTemplateMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @Author sk
 * @Description:
 * @Date 2022/12/21 14:14
 **/
@Service
@Slf4j
public class ExpertSmsServiceImpl implements IExpertSmsService {

    @Autowired
    ExpertInvitationMapper invitationMapper;

    @Autowired
    ExpertRuleUserMapper expertRuleUserMapper;

    @Autowired
    ExpertInvitationRuleMapper expertInvitationRuleMapper;

    @Autowired
    SmsClientFactory smsClientFactory ;

    @Autowired
    SmsTemplateMapper smsTemplateMapper;
    @Override
    public void smsMonitor() {
        /**
         * 获取监控列表
         */
        List<ExpertInvitationDo> monitorList = invitationMapper.getMonitorList();
        if (!monitorList.isEmpty()) {
            monitorList.forEach(e -> {

                Long invitationId = e.getId();
                /**
                 * 邀请码失效分钟数
                 */
                Integer expiration_minutes =     e.getExpirationTime();
                /**
                 * 获取 邀约规则 一级规则下的备选专家
                 */
                List<ExpertInvitationRuleDo> ruleList = expertInvitationRuleMapper.getByInvitationId(invitationId);

                ruleList.forEach(r -> {
                    Long ruleId = r.getId();
                    /**
                     * 预邀人数
                     */
                    Integer inviteesNumbers = r.getInviteesNumbers();

                    Integer effectiveCount =  expertRuleUserMapper.countEffective(ruleId);
                    /**
                     * 判断当前 名单是否已经足够
                     * 选择范围
                     *  已经发过短信 （已经确认参加的数量+未超时切待确认的数量）)>inviteesNumbers
                     *  则停止发送短信
                     *  否则 再从待选专家池中 选择 （inviteesNumbers-（已经确认参加的数量+未超时切待确认的数量）)
                     *  个专家发送邀请短信
                     *
                     */

                    Integer diffCount = inviteesNumbers-effectiveCount;
                    if(diffCount>0){
                        /**
                         * 获取备用专家
                         */
                        List<ExpertRuleUserDo> expertRuleUserDos =
                                this.expertRuleUserMapper.getSpareList(ruleId);
                        if(expertRuleUserDos.isEmpty()){
                            return;
                        }
                        Integer spareSize = expertRuleUserDos.size();

                        Integer index = 0;

                        if(diffCount>=spareSize){
                            index = spareSize-1;
                        }else {
                            index = diffCount-1;
                        }
                        /**
                         * 循环发送短信
                         */
                        SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectByCode("EXPERT_NOTICE");

                        if(Objects.isNull(smsTemplateDO)){
                            log.error("短信模板配置错误");
                            return;
                        }

                        for(int i=0;i<=index;i++){
                            ExpertRuleUserDo expertRuleUserDo =  expertRuleUserDos.get(i);
                            /**
                             * send message
                             */
                            SmsClient tencentSmsClient = this.smsClientFactory.getSmsClient(SmsChannelEnum.TENCENT.getCode());
                            String phone = expertRuleUserDo.getPhone();

                            String invitationCode = RandomUtils.generatesNumNonceStr(6);
                            expertRuleUserDo.setInvitationCode(invitationCode);

                            Date expirationTime = DateUtil.offsetMinute(new Date(),expiration_minutes);
                            expertRuleUserDo.setExpirationTime(expirationTime);

                            List<KeyValue<String,Object>> params =createParams(e,expertRuleUserDo);

                            try {

                                String apiTemplateId = smsTemplateDO.getApiTemplateId();

                                SmsCommonResult<SmsSendRespDTO> respDTOSmsCommonResult =  tencentSmsClient.sendSms(System.currentTimeMillis(),phone,apiTemplateId,params);
                                String apiCode = respDTOSmsCommonResult.getApiCode();
                                expertRuleUserDo.setSendTime(new Date());

                                if("Ok".equals(apiCode)){
                                    /**
                                     * 确认短信是否发送成功
                                     * 成功则更新数据
                                     */
                                    expertRuleUserDo.setSendStatus(1);
                                }else {
                                    expertRuleUserDo.setSendStatus(-1);
                                    log.error("发送短信失败{}",respDTOSmsCommonResult.getApiMsg());
                                }
                                expertRuleUserDo.setSendResult(respDTOSmsCommonResult.getApiMsg());

                                this.expertRuleUserMapper.updateById(expertRuleUserDo);
                            }catch (Exception s){
                                log.error("发送短信失败",s);
                            }


                        }
                    }

                });

            });
        }
    }

    /**
     * 功能描述: 组装参数
     * @author sk
     * @date 2022/12/26
     * @param e 邀约信息
     * @param expertRuleUserDo 专家信息
     * @return java.util.List<com.unidt.www.framework.common.core.KeyValue<java.lang.String,java.lang.Object>>
     */

    private List<KeyValue<String,Object>>  createParams(ExpertInvitationDo e,ExpertRuleUserDo expertRuleUserDo ){

        List<KeyValue<String,Object>> params = new ArrayList<>();
        params.add(new KeyValue(1,expertRuleUserDo.getName()) );
        params.add(new KeyValue(2,e.getSubject()));
        params.add(new KeyValue(3,expertRuleUserDo.getInvitationCode()));

        params.add(new KeyValue(4,DateUtil.formatDateTime(e.getStartTime())));

        params.add(new KeyValue(5,e.getAddress()));
        params.add(new KeyValue(6,e.getExpirationTime()+"分钟"));
        params.add(new KeyValue(7,e.getContacts()));
        params.add(new KeyValue(8,e.getContactsPhone()));
        return params;
    }
}
